package com.xlh.aop;

import com.xlh.common.ResultEnum;
import com.xlh.exception.common.GlobalException;
import com.xlh.lock.KeyLock;
import com.xlh.util.AnnotationResolver;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.concurrent.TimeUnit;


/**
 * 一个方法只有在获取锁后才能执行
 *
 * @author cheer
 */
@Aspect
@Component
public class AcquireLockAspect {

    @Autowired
    private KeyLock<String> lock;

    @Before("@annotation(PreAcquireLock)")
    public void requireLock(JoinPoint joinPoint) {
        Signature signature = joinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        Method method = methodSignature.getMethod();
        PreAcquireLock preAcquireLock = method.getAnnotation(PreAcquireLock.class);

        String key = AnnotationResolver.resolver(joinPoint, preAcquireLock.value());
        int timeout = preAcquireLock.timeout();
        String message = preAcquireLock.message();

        if (timeout == 0) {
            if (!lock.tryLock(key)) {
                throw new GlobalException(message);
            }
        } else {
            if (!lock.tryLock(key, timeout, TimeUnit.SECONDS)) {
                throw new GlobalException(message);
            }
        }
    }

}
